package com.taomus.mytools.lang.js.mozilla;

import java.io.IOException;
import java.io.InputStream;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.taomus.mytools.helper.stream.StreamHelper;


public class JSHelper {

	private final static Logger logger = LoggerFactory.getLogger(JSHelper.class);

	private Context cx;
	private Scriptable scope;
	
	private StringBuffer jsSource = new StringBuffer();
	

	public JSHelper() {
		cx = Context.enter();
		scope = cx.initStandardObjects();
		try {
			InputStream input = StreamHelper.getInputStreamByFileName("com/taomus/mrc/mytools/lang/js/mozilla/json2.min.js");
			loadCode(StreamHelper.getContent(input));
		} catch (IOException e) {
			logger.error("JSHelper static init error : ",e);
		}
	}

	public JSHelper(String filename) {
		this();
		load(filename);
	}

	public JSHelper(String[] filenames) {
		this();
		loads(filenames);
	}

	/**
	 * 加载单个js文件
	 * @param filename String
	 */
	public void load(String filename) {
		try {
			logger.debug(filename);
			InputStream input = StreamHelper.getInputStreamByFileName(filename);
			jsSource.append(StreamHelper.getContent(input));
			loadCoding();
			logger.debug("load " + filename);
		} catch (IOException e) {
			Context.exit();
			logger.error("IOException",e);
		}
	}

	/**
	 * 加载多个js文件
	 * 
	 * @param filename
	 */
	public void loads(String[] filename) {
		try {
			for (String name : filename) {
				logger.debug(name);
				InputStream input = StreamHelper.getInputStreamByFileName(name);
				jsSource.append(StreamHelper.getContent(input));
			}
			loadCoding();
		} catch (IOException e) {
			Context.exit();
			logger.error("IOException",e);
		}
	}

	/**
	 * 加载源码
	 * @param source
	 */
	public void loadCode(String code) {
		jsSource.append(code);
		loadCoding();
	}
	
	/**
	 * 追加源码
	 * @param source
	 */
	public void append(String source){
		jsSource.append(source);
		loadCoding();
	}

	private void loadCoding() {
		cx.evaluateString(scope, jsSource.toString(), null, 1, null);
	}

	public JSField getField(String name) {
		return new JSField(name, scope);
	}
	
	public JSField addField(String name){
		return this.getField(name);
	}

	public JSMethod getMethod(String name) {
		return new JSMethod(name, cx, scope);
	}

	public Context getContext() {
		return cx;
	}

	public Scriptable getScope() {
		return scope;
	}
	
	public void exit(){
		Context.exit();
	}

}
